import { SocketOption } from "./SocketOption";
import { LOCAL_SOCKET_SERVER_HOST } from "@/constants/constants";
import { controller } from "../engine/Controller";
import { InstancetableCellMarkDto } from "@/constants/types";
import { ipcRenderer } from "electron";
import { IpcMsg, MessageChannelType } from "@/engine/types/Ipc";
import { SignalType, InfoLevel, LogRecord, SocketUpdateVariableMsg, ConstraintVariationNotice, SceneData, SimulateStatusType, SceneState } from "@/engine/_";
import { AnimationActivityStatusNotice } from "@/engine/types/Status";
import { ClientShowSimVariableData, UIOpenNotificationData } from "@/engine/types/Socket";
import { SimType, HiddenStatus } from "@/engine/types/Controller";
import { SimFrameToSubChannel, SubWinName, WinName } from "@/engine/types/Win";
import { TimeSeryUpdate, TimelineUpdateData } from "@/engine/types/charts";
export class SimulationSocketOption extends SocketOption {

  uri = LOCAL_SOCKET_SERVER_HOST + "websocket/simulation";

  devSocketMessageFilter: string[] = [
    'thread',
    'CLOCK_TIME'
  ];

  msgHandler = {
    infoSocketMessage: (data: any) => {
      if (process.env.NODE_ENV === "development") {
        if (this.devSocketMessageFilter.includes(data.type)) {
          console.info("ws:", data.type, data);
        }
      } else {
        console.info("ws:", data.type, data);
      }
    },

    console: (res: { data: LogRecord }) => {
      controller.consoleService.addRecord(res.data);
    },

    api_session_bind: () => {},
    init_sessions: () => {},
    api_start_step: () => {},
    connect: () => {},
    status: () => {},
    ui_activity_action: () => {},
    api_next_finish: () => {},
    api_interval: () => {},
    api_export_instance_table: () => {},

    refresh_sessions: async (res: { data: SceneData[] }) => {
      await controller.sceneService.refreshSessions(res.data);
    },

    /** 刷新场景状态 */
    refresh_scene_status: async (res: { data: { targetId: string, status: SceneState } }) => {
      const { data: { targetId, status } } = res;
      await controller.sceneService.refreshSceneStatus(targetId, status);
    },

    /* sim-process variable show on m-design */
    api_value_property_variation_notice: (res: { data: ClientShowSimVariableData }) => {
      controller.variableService.dealAndSendMainWinNoticeVariable(res.data);
    },

    animation_activity_status_notice: (res: { data: AnimationActivityStatusNotice }) => {
      if (!controller.simulationConfig.silent) {
        controller.simStatus.dealSimStatus(res.data);
      }
    },

    thread: (res: { message: string, data: { modelId: string } }) => {
      setTimeout(() => {
        if (res.message === "end") {
          controller.toolbarService.status = SimulateStatusType.finish;
          if (!controller.instanceTable.isTableSim(controller.type as SimType)) {
            controller.toolbarService.simFinishUiSet();
          }
          if (controller.instanceTable.isTableInstanceSim(controller.type as SimType)) {
            controller.ipcService.send( // fresh m-design table
              WinName.MainWindow,
              MessageChannelType.InstanceTableSimEnd
            );
          }
          // 清空仿真时钟
          controller.clockService.clearClock();
          // 清空场景信号
          controller.toolbarService.clearSignal();
        }
      }, 500);
    },

    api_instance_defining_feature_constraint: (res: { data: InstancetableCellMarkDto[] }) => {
      ipcRenderer.send(IpcMsg.MarkInstanceTableCells, {
        projectId: controller.projectId,
        data: res.data
      });
    },

    api_value_variation_notice: (res: { data: SocketUpdateVariableMsg[] }) => {
      controller.variableService.apiValueVariationNotice(res.data);
    },

    api_constraint_variation_notice: (res: { data: ConstraintVariationNotice}) => {
      controller.variableService.apiConstraintVariationNotice(res.data);
    },

    api_suspend: () => {
      controller.toolbarService.backendPauseSimulation();
    },

    step: () => {
      controller.toolbarService.firstStep = false;
    },

    api_get_signal: (res: { data: SignalType[] }) => {
      controller.toolbarService.signalList = res.data;
    },

    guard: (res: { data: { guardText: string, executionId: string, edgeId: string } }) => {
      controller.guard(res.data);
    },

    api_display_simulate_ui: async (res: { data: UIOpenNotificationData[] }) => {
      controller.winService.framesData = res.data;
      // 收到仿真UI配置信息，开始解析并自动开始仿真
      await controller.winService.dealFramesData();
      controller.afterDealFramesData();
    },

    ui_image_switcher_status: (res: { data: string }) => {
      controller.imageSwitcherService.doSwitch(res.data);
    },

    server_error: (err: {code: number, message: string, type: string }) => {
      controller.consoleService.addRecord({ level: InfoLevel.ERROR, message: err.message });
      controller.toolbarService.finishSimulation();
    },

    api_pin_action_sequence: (res: any) => {
      controller.docxService.transferDataToPinExportWin(res.data);
    },
    api_uicontrol: (res: any) => { // ue4-translate
      controller.ue4Service.transfer(JSON.parse(res.data));
    },
    ibd_connector: (res: { data: { content: string, modelId: string } }) => { // info-stream table
      controller.ipcService.send(
        WinName.MainWindow,
        MessageChannelType.ShowConnectMsg,
        {
          modelId: res.data.modelId,
          info: res.data.content,
        }
      );
    },
    api_info_flow_defining_feature_constraint: (res: any) => {
      controller.ipcService.send(
        WinName.MainWindow,
        MessageChannelType.TableConstantVerify,
        { info: res.data }
      );
    },
    line_activity_status_notice: (res: {data: TimelineUpdateData}) => { // timeline activity update
      if (res.data) {
        controller.winService.sendInfoToSubWins(
          {
            type: SimFrameToSubChannel.TimelineActivityUpdate,
            data: res.data,
          },
          SubWinName.Timeline
        );
      }
    },
    line_state_status_notice: (res: {data: TimelineUpdateData}) => { // timeline status update
      controller.winService.sendInfoToSubWins(
        {
          type: SimFrameToSubChannel.TimelineStatusUpdate,
          data: res.data,
        },
        SubWinName.Timeline
      );
    },
    CLOCK_TIME_PUSH: (res: {data: {currentTime: number, data: any, consumers: string[]}}) => {
      controller.winService.sendInfoToSubWins(
        {
          type: SimFrameToSubChannel.UpdateChartsData,
          data: {
            simulationSessionId: controller.sessionId,
            times: res.data.currentTime,
            data: res.data.data,
            consumers: res.data.consumers
          },
        },
        SubWinName.Charts
      );
    },
    /**
     * 仿真时钟v2
     * @param res
     */
    CLOCK_TIME: (res: {data: {currentTime: number, data: any, consumers: string[]}}) => {
      controller.clockService.setClockTime(res.data.currentTime);
      // 初始化成功后，推送一条数据到控制台
      if (!controller.consoleService.isInit) {
        controller.consoleService.addRecord({ level: InfoLevel.INFO, message: controller.locale.localeTrans('init_simulation') });
      }
    },
  }
}

